package com.kgcx.common.aspect;

import com.alibaba.fastjson.JSONObject;
import com.kgcx.common.bean.ReturnData;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;

/**
 * mq消费者日志切面
 * @author wuganglin
 * Created by Administrator on 2017/2/20.
 */
@Component
@Aspect
@SuppressWarnings("unchecked")
public class ConsumerLogAspect {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());


    @Pointcut("@annotation(org.springframework.amqp.rabbit.annotation.RabbitListener)")
    public void pointcut() {
    }

    //应用周围通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint call) {
        try {
            Signature signature = call.getSignature();
            /*if (!(signature instanceof MethodSignature)) {
                throw new IllegalArgumentException("该注解只能用于方法");
            }*/
            MethodSignature msig = (MethodSignature) signature;
            Object[] args = call.getArgs();
            Object target = call.getTarget();
            Logger logger = getLogger(target);

            String methodName = target.getClass().getSimpleName() + "." + msig.getName() + "()";

            logBefore(logger, methodName + "---" + JSONObject.toJSONString(args));

            //无校验失败信息,则正常执行方法


            call.proceed();

            logAfter(logger, methodName + "---");
        } catch (Throwable e) {
            this.logger.error("内部错误", e);
            return new ReturnData("-1", "内部错误！");
        }
        return null;
    }

    private Logger getLogger(Object target) {
        Field[] declaredFields = target.getClass().getDeclaredFields();
        Logger logger = this.logger;
        if (ArrayUtils.isNotEmpty(declaredFields)) {
            for (Field declaredField : declaredFields) {
                if (Logger.class.isAssignableFrom(declaredField.getType())) {
                    ReflectionUtils.makeAccessible(declaredField);
                    logger = (Logger) ReflectionUtils.getField(declaredField, target);
                    return logger;
                }
            }
        }
        return logger;
    }

    public void logBefore(Logger logger, String interfaceName) {
        logger.info("");
        logger.info("start consumer");
        logger.info(interfaceName);
    }


    public void logAfter(Logger logger, String interfaceName) {
        logger.info(interfaceName);
        logger.info("end consumer");
        logger.info("");
    }


}
